//
// Created by zhouyi on 2019-11-29.
//

#include "JavaCallHelper.h"

JavaCallHelper::JavaCallHelper(JavaVM *_javaVM, JNIEnv *_env, jobject &_jobj) : javaVM(_javaVM),
                                                                                env(_env) {
    jobj = env->NewGlobalRef(_jobj);
    jclass jclazz = env->GetObjectClass(jobj);

    jmid_error = env->GetMethodID(jclazz, "onError", "(I)V");
    jmid_prepare = env->GetMethodID(jclazz, "onPrepare", "()V");
    jmid_progress = env->GetMethodID(jclazz, "onProgress", "(I)V");
}


JavaCallHelper::~JavaCallHelper() {
    env->DeleteLocalRef(jobj);
    jobj = nullptr;
}


void JavaCallHelper::onError(int code, int thread) {
    callJavaMethod(thread, jmid_error, code);
}

void JavaCallHelper::onPrepared(int thread) {
    callJavaMethod(thread, jmid_prepare);
}


void JavaCallHelper::onProgress(int progress, int thread) {
    callJavaMethod(thread, jmid_progress, progress);
}


void JavaCallHelper::callJavaMethod(int thread, jmethodID jmid, ...) const {
    va_list args;
    // va_start使参数列表指针args指向函数参数列表中的第一个可选参数，jmid是位于第一个可选参数之前的固定参数
    va_start(args, jmid);

    if (thread == THREAD_CHILD) {
        // 子线程
        JNIEnv *jniEnv;
        // 获取一个当前线程的env，然后当前的env去掉用java方法
        if (javaVM->AttachCurrentThread(&jniEnv, nullptr) != JNI_OK) {
            return;
        }
        jniEnv->CallVoidMethod(jobj, jmid, args);
        // 解绑
        javaVM->DetachCurrentThread();


    } else {
        env->CallVoidMethod(jobj, jmid);
    }

    va_end(args);
}